﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace WHControlLib.IconFont
{
    public class ImageFont
    {
      


        private readonly IntPtr memoryFont = IntPtr.Zero;
        public PrivateFontCollection pfc = new PrivateFontCollection();
        /// <summary>
        /// 字体图标集在内存中读取的构造方法
        /// </summary>
        /// <param name="buffer"></param>
        public ImageFont(byte[] buffer)
        {
           
           if (buffer==null)
                {
                    return;
                }
            try
            {
              
             memoryFont = Marshal.AllocCoTaskMem(buffer.Length);
            Marshal.Copy(buffer, 0, memoryFont, buffer.Length);

            pfc.AddMemoryFont(memoryFont, buffer.Length);
            }
            catch (Exception)
            {

                //throw;
            }
          
        }
        /// <summary>
        /// 字体图标在文件中读取的构造方法
        /// </summary>
        /// <param name="FileName"></param>
        public ImageFont(string FileName)
        {

            if (File.Exists(FileName))
            {

                pfc.AddFontFile(FileName);
            }
        }

    }

    public static class FontImageHelper
    {
        public const int MaxSize = 105;
        public const int MinSize = 5;
        const string IconResoucePath = "WHControlLib.IconFont.FontAwesome.ttf";
        public static ImageFont imageFontsRes;
        public static readonly int Count = 0;
        /// <summary>
        /// 所有可用数字的List
        /// </summary>
        public static List<int> ImageFontContainIntsList = new List<int>();
     
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <exception cref="Exception"></exception>
        static FontImageHelper()
        {

            try
            {
           imageFontsRes = new ImageFont(ReadFontFileFromResource(IconResoucePath));
            int[] imageFontvalues = (int[])Enum.GetValues(typeof(FontImagesEnum.FontIcons));
            //只使用A开头的常量
            foreach (var item in imageFontvalues)
            {
                string t = Enum.GetName(typeof(FontImagesEnum.FontIcons), item);
                var ts = t.ToArray();
                if (ts.Length > 1 && ts[0] == 'A')
                {
                    ImageFontContainIntsList.Add(item);
                }

            }

            Count = ImageFontContainIntsList.Count;
            }
            catch (Exception)
            {

                throw new Exception("图标字符集初始化失败!");
            }
           


        }

        /// <summary>
        /// 将资源文件读入内存缓冲区
        /// </summary>
        /// <param name="name">嵌入资源文件路径</param>
        /// <returns></returns>
        private static byte[] ReadFontFileFromResource(string name)
        {
            byte[] buffer = null;
            Stream fontStream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(name);
            if (fontStream != null)
            {
                buffer = new byte[fontStream.Length];
                fontStream.Read(buffer, 0, (int)fontStream.Length);
                fontStream.Close();
            }

            return buffer;
        }


       /// <summary>
       /// 获得数字所对应的字符
       /// </summary>
       /// <param name="StrInt">图标字符标号</param>
       /// <returns>Unicode图标字符</returns>
        public static string GetFontFromIntNumber(int StrInt)
        {
            return char.ConvertFromUtf32(StrInt);
        }
        /// <summary>
        /// 检查是否数字是否在可生成图片范围
        /// </summary>
        /// <param name="StrInt"></param>
        /// <returns></returns>
        public static bool CheckIsContainInt(int StrInt)
        {
            if (ImageFontContainIntsList.Count > 0 && ImageFontContainIntsList.Contains(StrInt))

                return true;
            else

                return false;
        }
        /// <summary>
        /// 获得字符图标的图片根据整型标号
        /// </summary>
        /// <param name="imageFontInt">图标整数标号</param>
        /// <param name="FontColor">图标颜色</param>
        /// <param name="imageSize">图标大小</param>
        /// <returns></returns>
        public static Bitmap GetImageFontBitmap(int imageFontInt, Color FontColor, int imageSize)
        {

            string str=GetFontFromIntNumber(imageFontInt);
            return GetImageFontBitmap(str,FontColor,imageSize);

        }
      /// <summary>
      /// 获得字符图标的图片，根据unicode字符
      /// </summary>
      /// <param name="imageFontstr"></param>
      /// <param name="FontColor"></param>
      /// <param name="imageSize"></param>
      /// <returns></returns>
        public static Bitmap GetImageFontBitmap(string imageFontstr, Color FontColor, int imageSize)
        {  
              if (imageSize< MinSize)
                {
                    imageSize = MinSize;
                }
                if (imageSize>MaxSize)
                {
                    imageSize = MaxSize;

                }
          
            try
            {
           
             Font myfon = new Font(imageFontsRes.pfc.Families[0], imageSize, FontStyle.Regular, GraphicsUnit.Point);
           
            Bitmap bit = new Bitmap(20, 20);
            Graphics g = Graphics.FromImage(bit);
            SizeF bitSize = g.MeasureString(imageFontstr, myfon);
            int RbitWidth = (int)bitSize.Width;
            int RbitHeight = (int)bitSize.Height;
            Bitmap Rbit = new Bitmap(RbitWidth, RbitHeight);
            StringFormat sf = new StringFormat();
            sf.Alignment = StringAlignment.Center;
            sf.LineAlignment = StringAlignment.Center;
            using (SolidBrush sb = new SolidBrush(FontColor))
            {
                Rectangle rect = new Rectangle();
                rect.Width = RbitWidth;
                rect.Height = RbitHeight;
                rect.X = 0;
                rect.Y = 0;

                using (Graphics rg = Graphics.FromImage(Rbit))
                {
                    rg.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
                    rg.InterpolationMode = InterpolationMode.HighQualityBilinear;
                    rg.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    rg.SmoothingMode = SmoothingMode.HighQuality;

                    rg.DrawString(imageFontstr, myfon, sb, rect, sf);
                }
            }

            g.Dispose();
            return Rbit;

            }
            catch (Exception)
            {

                //throw;
                return null;
            }
           
           

           

        }
        public static Icon BitmapToIcon(Bitmap srcBitmap, int size)
        {
            if (srcBitmap == null)
            {
                throw new ArgumentNullException(nameof(srcBitmap));
            }

            Icon icon;
            using (MemoryStream memoryStream = new MemoryStream())
            {
                new Bitmap(srcBitmap, new Size(size, size)).Save(memoryStream, ImageFormat.Png);
                Stream stream = new MemoryStream();
                BinaryWriter binaryWriter = new BinaryWriter(stream);
                if (stream.Length <= 0L)
                {
                    return null;
                }

                binaryWriter.Write((byte)0);
                binaryWriter.Write((byte)0);
                binaryWriter.Write((short)1);
                binaryWriter.Write((short)1);
                binaryWriter.Write((byte)size);
                binaryWriter.Write((byte)size);
                binaryWriter.Write((byte)0);
                binaryWriter.Write((byte)0);
                binaryWriter.Write((short)0);
                binaryWriter.Write((short)32);
                binaryWriter.Write((int)memoryStream.Length);
                binaryWriter.Write(22);
                binaryWriter.Write(memoryStream.ToArray());
                binaryWriter.Flush();
                binaryWriter.Seek(0, SeekOrigin.Begin);
                icon = new Icon(stream);
                stream.Dispose();
            }

            return icon;
        }
        /////////////////////////////////////////////////////////////////////////

    }
}
